﻿using Microsoft.Extensions.Configuration;

namespace CleanLite.Shared.Configuration
{
    /// <summary>
    /// 配置读取服务文件[静态类,全局可使用]
    /// </summary>
    public static class ConfigurationService
    {
        //私有静态实例
        private static IConfiguration? Configuration { get; set; }

        /// <summary>
        /// 初始化配置方法
        /// </summary>
        /// <param name="configuration"></param>
        public static void Initialize(IConfiguration configuration)
        {
            if (Configuration != null)
            {
                return;
            }
            Configuration = configuration;
        }

        /// <summary>
        /// 初始化配置方法2[读取指定位置配置文件]
        /// </summary>
        /// <param name="basePath">路径</param>
        /// <param name="fileName">文件名</param>
        /// <exception cref="FileNotFoundException">未找到文件</exception>
        public static void Initialize(string basePath, string fileName)
        {
            if (Configuration != null)
            {
                return;
            }
            try
            {
                Configuration = new ConfigurationBuilder()
                     .SetBasePath(basePath)
                     .AddJsonFile(fileName, false, true)
                     .Build();
            }
            catch (Exception)
            {
                throw new FileNotFoundException($"未在指定位置找到配置文件{Path.Combine(basePath, fileName)}");
            }
        }

        public static IConfiguration Current
        {
            get
            {
                if (Configuration == null)
                {
                    throw new Exception("请先调用Initialize方法进行初始化");
                }
                return Configuration;
            }
        }

        #region 使用方法

        /// <summary>
        /// 读取指定节点绑定为实体对象
        /// </summary>
        /// <typeparam name="T">实体</typeparam>
        /// <param name="paras">参数</param>
        /// <returns>实体对象(节点下无内容返回空实体)</returns>
        public static T GetSection<T>(params string[] paras) where T : new()
        {
            return Current.GetSection(string.Join(":", paras)).Get<T>() ?? new T();
        }

        /// <summary>
        /// 读取指定节点绑定为实体对象集合
        /// </summary>
        /// <typeparam name="T">实体</typeparam>
        /// <param name="paras">参数</param>
        /// <returns>实体对象(节点下无内容返回空实体集合)</returns>
        public static List<T> GetSectionList<T>(params string[] paras) where T : new()
        {
            return Current.GetSection(string.Join(":", paras)).Get<List<T>>() ?? new List<T>();
        }

        public static T[] GetSectionArray<T>(params string[] paras) where T : new()
        {
            return Current.GetSection(string.Join(":", paras)).Get<T[]>() ?? [];
        }

        /// <summary>
        /// 读取指定节点的内容
        /// </summary>
        /// <param name="paras">参数</param>
        /// <returns>字符串(节点下无内容返回空字符串)</returns>
        public static string GetString(params string[] paras)
        {
            return Current[string.Join(":", paras)] ?? string.Empty;
        }

        /// <summary>
        /// 读取指定节点的内容集合
        /// </summary>
        /// <param name="paras">参数</param>
        /// <returns>字符串集合(节点下无内容返回空集合)</returns>
        public static List<string> GetStringList(params string[] paras)
        {
            return Current.GetSection(string.Join(":", paras)).Get<List<string>>() ?? [];
        }

        /// <summary>
        /// 读取指定节点的内容数组
        /// </summary>
        /// <param name="paras">参数</param>
        /// <returns>字符串数组(节点下无内容返回空集合)</returns>
        public static string[] GetStringArray(params string[] paras)
        {
            return Current.GetSection(string.Join(":", paras)).Get<string[]>() ?? [];
        }

        /// <summary>
        /// 读取指定节点下的键值对集合
        /// </summary>
        /// <param name="paras">参数</param>
        /// <returns>键值对集合(节点下无内容返回空集合)</returns>
        public static List<KeyValuePair<string, string?>> GetKeyValues(params string[] paras)
        {
            return [.. Current.GetSection(string.Join(":", paras))
                .GetChildren()
                .Select(x => new KeyValuePair<string, string?>(x.Key, x.Value))];
        }

        /// <summary>
        /// 获取bool值
        /// </summary>
        /// <param name="paras">参数</param>
        /// <returns>true or false</returns>
        public static bool GetBool(params string[] paras)
        {
            var value = Current[string.Join(":", paras)];
            return bool.TryParse(value, out var result) && result;
        }

        /// <summary>
        /// 获取Int值
        /// </summary>
        /// <param name="paras">参数</param>
        /// <returns>返回结果或0</returns>
        public static int GetInt(params string[] paras)
        {
            var value = Current[string.Join(":", paras)];
            return int.TryParse(value, out var result) ? result : 0;
        }

        #endregion 使用方法
    }
}